package ioc.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.stereotype.Component;
import org.springframework.util.StringValueResolver;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * 指定初始化和销毁方法，使用 JSR250 规范
 * * @PostConstruct：在 bean 创建完成并且属性赋值完成后执行
 * * @PreDestroy：在容器销毁 bean 之前执行
 * <p>
 * Spring 内部对 BeanPostProcessor 的使用
 * * @Value bean赋值；
 * * @Autowired 注入其他组件；
 * * @Async 异步方法;
 * * @PostConstruct 生命周期注解功能；
 * * @PreDestroy 生命周期注解功能；
 * ApplicationContextAware：让 Bean 可以使用 IOC 容器；===》ApplicationContextAwareProcessor
 * 等等。。。。。。
 * <p>
 * 自定义组件想使用 spring 的功能实现 xxxAware 即可
 * 自动装配：Spring 利用依赖注入（DI），完成对 IOC 容器中中各个组件的依赖关系赋值；
 * 自定义组件想要使用 Spring 容器底层的一些组件（ApplicationContext，BeanFactory......）；
 * 自定义组件实现 xxxAware；在创建对象的时候，会调用接口规定的方法注入相关组件；Aware；
 * xxxAware：功能使用 xxxProcessor；
 * ApplicationContextAware==》ApplicationContextAwareProcessor implements BeanPostProcessor；
 */
@Component
public class Dog implements InitializingBean, DisposableBean, ApplicationContextAware, BeanNameAware, EmbeddedValueResolverAware {

    ApplicationContext applicationContext;

    public Dog() {
        System.out.println("dog constructor...");
    }

    public void initx() {
        System.out.println("car ... initx...");
    }

    public void destoryx() {
        System.out.println("car ... detoryx...");
    }

    @PostConstruct // 对象创建并赋值之后调用
    public void init() {
        System.out.println("Dog....@PostConstruct...");
    }

    @PreDestroy // 容器移除对象之前
    public void detory() {
        System.out.println(applicationContext.getId());
        System.out.println("Dog....@PreDestroy...");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("cat...destroy...");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("cat...afterPropertiesSet...");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("传入的ioc：" + applicationContext);
        this.applicationContext = applicationContext;
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("当前bean的名字：" + name);
    }

    @Override
    public void setEmbeddedValueResolver(StringValueResolver resolver) {
        String resolveStringValue = resolver.resolveStringValue("你好 ${os.name} 我是 #{20*18}");
        System.out.println("解析的字符串：" + resolveStringValue);
    }
}
